package com.cmic.rcs.emoji.common.encrypt;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

@Slf4j
public class AES128 {

    /**
     * 加密算法
     */
    private static final String ENCRY_ALGORITHM = "AES";

    /**
     * 加密算法/加密模式/填充类型
     * 本例采用AES加密，ECB加密模式，PKCS5Padding填充
     */
    private static final String CIPHER_MODE = "AES/ECB/PKCS5Padding";

    /**
     * 设置iv偏移量
     * 本例采用ECB加密模式，不需要设置iv偏移量
     */
    private static final String IV_ = null;

    /**
     * 设置加密字符集
     * 本例采用 UTF-8 字符集
     */
    private static final String CHARACTER = "UTF-8";

    /**
     * 设置加密密码处理长度。
     * 不足此长度补0；
     */
    private static final int PWD_SIZE = 16;

    private static final Base64.Decoder decoder = Base64.getDecoder();
    private static final Base64.Encoder encoder = Base64.getEncoder();


    /**
     * 密码处理方法
     * 如果加解密出问题，
     * 请先查看本方法，排除密码长度不足填充0字节,导致密码不一致
     * @param password 待处理的密码
     * @return
     * @throws UnsupportedEncodingException
     */
    private static byte[] pwdHandler(String password) throws UnsupportedEncodingException {
        byte[] data = null;
        if (password != null) {
            byte[] bytes = password.getBytes(StandardCharsets.UTF_8);
            if (password.length() < PWD_SIZE) {
                System.arraycopy(bytes, 0, data = new byte[PWD_SIZE], 0, bytes.length);
            } else {
                data = bytes;
            }
        }
        return data;
    }

    /**
     * 密码处理方法
     * 如果加解密出问题，
     * 请先查看本方法，排除密码长度不足填充0字节,导致密码不一致
     * @param password 待处理的密码
     * @return
     * @throws UnsupportedEncodingException
     */
    private static byte[] pwdHandler(byte[] password) throws UnsupportedEncodingException {
        byte[] data = null;
        if (password != null) {
            if (password.length < PWD_SIZE) {
                System.arraycopy(password, 0, data = new byte[PWD_SIZE], 0, password.length);
            } else {
                data = password;
            }
        }
        return data;
    }

    /**
     * 原始加密
     * @param plain 待加密字符串
     * @return 返回加密后的base64密文，加密错误返回null
     */
    public static String encrypt(String plain, String AESKey) {
        try {
            // 1 获取加密密钥
            SecretKeySpec keySpec = new SecretKeySpec(pwdHandler(decoder.decode(AESKey.getBytes(StandardCharsets.UTF_8))), ENCRY_ALGORITHM);

            // 2 获取Cipher实例
            Cipher cipher = Cipher.getInstance(CIPHER_MODE);

            // 查看数据块位数 默认为16（byte） * 8 =128 bit
//            System.out.println("数据块位数(byte)：" + cipher.getBlockSize());

            // 3 初始化Cipher实例。设置执行模式以及加密密钥
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);

            // 4 执行
            byte[] cipherTextBytes = cipher.doFinal(plain.getBytes(StandardCharsets.UTF_8));

            // 5 返回密文字符集
//            return bytesToHexString(cipherTextBytes);
            return new String(encoder.encode(cipherTextBytes), StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("", e);
            return null;
        }
    }

    /**
     * 原始加密
     * @param plain 待加密字符串
     * @return 返回加密后的base64密文，加密错误返回null
     */
    public static String encryptToHexString(String plain, String AESKey) {
        try {
            // 1 获取加密密钥
            SecretKeySpec keySpec = new SecretKeySpec(pwdHandler(decoder.decode(AESKey.getBytes(StandardCharsets.UTF_8))), ENCRY_ALGORITHM);

            // 2 获取Cipher实例
            Cipher cipher = Cipher.getInstance(CIPHER_MODE);

            // 查看数据块位数 默认为16（byte） * 8 =128 bit
//            System.out.println("数据块位数(byte)：" + cipher.getBlockSize());

            // 3 初始化Cipher实例。设置执行模式以及加密密钥
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);

            // 4 执行
            byte[] cipherTextBytes = cipher.doFinal(plain.getBytes(StandardCharsets.UTF_8));

            // 5 返回密文字符集
//            return bytesToHexString(cipherTextBytes);
            return Hex.encodeHexString(cipherTextBytes);
        } catch (Exception e) {
            log.error("", e);
            return null;
        }
    }

    /**
     * 原始解密
     * @param encodeText base64密文
     * @return 返回解密后的明文，解密错误返回null
     */
    public static String decrypt(String encodeText, String AESKey) {
        try {
            // 1 获取解密密钥
            SecretKeySpec keySpec = new SecretKeySpec(pwdHandler(decoder.decode(AESKey.getBytes(StandardCharsets.UTF_8))), ENCRY_ALGORITHM);

            // 2 获取Cipher实例
            Cipher cipher = Cipher.getInstance(CIPHER_MODE);

            // 查看数据块位数 默认为16（byte） * 8 =128 bit
//            System.out.println("数据块位数(byte)：" + cipher.getBlockSize());

            // 3 初始化Cipher实例。设置执行模式以及加密密钥
            cipher.init(Cipher.DECRYPT_MODE, keySpec);

            byte[] decodeBytes = decoder.decode(encodeText.getBytes(StandardCharsets.UTF_8));
//            byte[] decodeBytes = hexStringToBytes(encodeText);

            // 4 执行
            byte[] clearTextBytes = cipher.doFinal(decodeBytes);

            // 5 返回明文字符串
            return new String(clearTextBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("", e);
            return null;
        }
    }

    private static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    private static String bytesToHexString(byte[] src) {
        if (src == null || src.length <= 0) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (byte cipherTextByte : src) {
            sb.append(String.format("%02x", cipherTextByte));
        }
        return sb.toString();
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        String str = new String(pwdHandler("-&7=ws7fBaXnC$EN"), StandardCharsets.UTF_8);
        String plain = "{test:13802885110,name:测试}";
        String encrty = encrypt(plain, encoder.encodeToString("ed26d4cd99aa11e5b8a4c89cdc776729".getBytes(StandardCharsets.UTF_8)));
        System.out.println(encrty);
        byte[] as = pwdHandler("sd#Vds3124!4z");
        byte[] as2 = pwdHandler(decoder.decode("c2QjVmRzMzEyNCE0eg==".getBytes(StandardCharsets.UTF_8)));
        String str2 = new String(as, StandardCharsets.UTF_8);
        System.out.println(str);
        System.out.println(str2);
        System.out.println(str2);
//        System.out.println(encrypt("{\"content_type\":\"text\",\"receiver\":\"335165785\",\"sender\":\"9008600000000\",\"member\":\"19802021720\",\"message_type\":\"2\",\"text\":\"测试回复\",\"uuid\":\"00da1c7e4b6e49a4b1a19ebbae3fad0f\"}",str));
        System.out.println(encrypt("{\"content_type\":\"text\",\"receiver\":\"30001217\",\"sender\":\"9008600000000\",\"member\":\"19802021720\",\"message_type\":\"2\",\"text\":\"测试机器人回复\",\"uuid\":\"00da1c7e4b6e49a4b1a19ebbae3fad0f\"}","akZ2RHctK2YwKE96XDRqSw=="));
        System.out.println(encrypt("{\"content_type\":\"text\",\"receiver\":\"335165785\",\"member\":\"robot999999\",\"sender\":\"19802021720\",\"message_type\":\"2\",\"text\":\"测试\",\"uuid\":\"00da1c7e4b6e49a4b1a19ebbae3fad0f\"}","akZ2RHctK2YwKE96XDRqSw=="));
        System.out.println(encrypt("{\"uuid\": \"c0fb136f741f11ec97f17cb0c2f6c26d\", \"member\": \"13502914496\", \"sender\": \"9008600000003\", \"receiver\": \"13502914496\", \"content_type\": \"text\", \"message_type\": \"1\", \"text\": \"test\"}","N3BsbG5oeTBlMkFxREtRYg=="));
        System.out.println(decrypt("zLE8+4jHSkDLqZXl+uhLw3yFGF05OB78sWgHESmRm37b0wyp877vtuCZ8j0JmECE0X4hB1U9HglPGP+HWOLX69QAyUV9Rv+fhimd3mwiPy2/n7t/EZj+zJki0FbWmEik0oS9E1asSy9kwrpLLX+1TK3xiU0XJ5jcnxwdkX/vgiY7Fr6bUMuiV9thNwR5kDJ+RIXGiX4c6OB61riJTqOuzLDDJw+kJEUYypizkrIYsgHXnL37iINsmOkANjBAEXKh","N3BsbG5oeTBlMkFxREtRYg=="));
    }

}
